POV-Ray : Newsgroups : povray.tools.general : tga->df3 : Re: tga->df3 Server Time
17 May 2024 04:44:41 EDT (-0400)
  Re: tga->df3  
From: Warp
Date: 4 Oct 2004 11:08:01
Message: <41616751@news.povray.org>
Some more comments:

  - This is more a question of programming style than anything else, but
it's usually considered a good style to not to have method implementations
in the public interface of a class. (Since implementation details are
hidden at programmatical level, it's a good idea to keep them more or
less hidden at visual level as well... :) )
  If you want to define inline functions, they can be implemented at
the end of the header. It requires more writing, but the declaration
of the class keeps cleaner and nicer to look at.
  That is, something along the lines of:

class FooBar
{
 public:
    ...
    inline bool someFlag() const;
    ...

 private:
    ...
};

inline bool FooBar::someFlag() const { return theFlag; }

  (Note that the 'inline' keyword is very important in this case. Do you
know why?
  When you implement the function in its declaration inside the class the
'inline' keyword is not needed (because it's implied), but doing it this
way requires 'inline'. But why?)

  - I personally also try to make class declarations look nicer by using
whitespaces and "separator comments" to my advantage. For example something
like this:

//===============================================================
// Appropriate description
// of 'SomeClass' here
//===============================================================
class SomeClass
{
 public:
    SomeClass();
    ~SomeClass();

    void someFunction();
    void anotherFunction();




//-------------------------------------------------------
 private:
//-------------------------------------------------------
    some;
    private;
    stuff;
    here;
};

  In the implementation I also usually use visible "separators" before
functions. Also try to group function implementations by category.
I often use "//======..." separators to start a category and
"//------..." separators to start a function (if I feel the function
needs one; they don't always do). Naturally I try to write something
descriptive between these lines :)
  It would thus look something like this:

//=======================================================================
// Constructor and destructor
//=======================================================================
SomeClass::SomeClass():
    initialize(some), stuff(here)
{
}

SomeClass::~SomeClass()
{
}



//=======================================================================
// Handler functions
//=======================================================================

//---------------------------------------------------------
// Do something 1
//---------------------------------------------------------
bool SomeClass::someFunction()
{
    ....
}

//---------------------------------------------------------
// Do something 2
//---------------------------------------------------------
bool SomeClass::anotherFunction()
{
    ....
}

  These separators make it easier to find things in the code.

  - Although in most cases it doesn't matter if you return a member
string by value or by const reference, it might be a good idea to
do the latter. Some compilers might not use the copy-on-write technique
for strings, and it's a good idea for other container types.
  That is, instead of:

  std::string getName() const;

it may be a good idea to do it like:

  const std::string& getName() const;

  (Note that this can only be done for methods which return a reference
to a member string or some other string which scope is not limited to
the function itself. If you are returning a string created inside the
function then you must do it by value.)

  - A C tip (which you might already know, but...): If you have tons
of boolean flags in your class and you don't want that class to be
very big (after all, each 'bool' is 4 bytes long even though it can
only have two values), you can use the bit field property of C.
That is, instead of doing this:

  bool a, b, c, d, e, f, g;

(which takes 28 bytes in a 32-bit system), you can do this:

  int a:1, b:1, c:1, d:1, e:1, f:1, g:1;

(which takes 4 bytes).

  The 'a', 'b', etc variables will still work as if they were of type bool
(by all practical effects), but will only take 1 bit each.
  It might not be the cleanest possible way of using flags (specially if
conserving space is not an issue), but it's certainly a lot cleaner than
trying to handle the individual bits yourself (with the above syntax it
will be the compiler which will generate the appropriate bit-handling
code).

  (Note that it's safe to use 'std::vector<bool>' without having to worry
about wasted space. std::vector has a specialization for the 'bool' type
in which each value takes only 1 bit of memory.)

  - There's an easier way of putting lots of strings (or any items) inside
a vector than writing tons of push_back lines. The more the items you need
to put in the vector, the more feasible this way is:

namespace
{
    const char* names[] =
    { "-b", "-f", "-h", "--help", ...
    };
}

arg::CL_Args::CL_Args(int argc, char* argv[]):
    switches(names, names+sizeof(names)/sizeof(names[0]))
{...}

  (If you can't use the constructor of the vector to put the values
in it, you can do it afterwards with:
switches.assign(names, names+sizeof(names)/sizeof(names[0]));)

  You can use this same feature to initialize your 'arguments' array:

arg::CL_Args::CL_Args(int argc, char* argv[]):
    switches(names, names+sizeof(names)/sizeof(names[0])),
    arguments(argv, argv+argc)
{...}

  (Or if afterwards: arguments.assign(argv, argv+argc);)

  The STL is quite ingenuous and versatile. Get to know it.

  - More later.

-- 
plane{-x+y,-1pigment{bozo color_map{[0rgb x][1rgb x+y]}turbulence 1}}
sphere{0,2pigment{rgbt 1}interior{media{emission 1density{spherical
density_map{[0rgb 0][.5rgb<1,.5>][1rgb 1]}turbulence.9}}}scale
<1,1,3>hollow}text{ttf"timrom""Warp".1,0translate<-1,-.1,2>}//  - Warp -


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.